module TprRoutine

using Printf
using Utils
using IndexParser
using Tpr

# TODO: 根据withDH调整输出结果
function tpr_functions(mdp::String, tprfilename::String, settings::Dict)
    println("\nChecking programs validity...")
    if !check_programs_validity(settings)
        error_hint("Program(s) not configured well. Check settings.ini.")
        return
    end
    ligand_grp = -1
    receptor_grp = -1
    complex_grp = -1
    trjfilename = ""
    ndxfilename = ""
    ndx = IndexParser.Index(Vector{IndexParser.IndexGroup}())
    useDH = true
    useTS = true
    while true
        println(h("\n                    ************ MMPBSA functions ************", fc="c"))
        println("-2 Toggle whether to use entropy contribution, current: $useTS")
        println("-1 Toggle whether to use Debye-Huckel shielding method, current: $useDH")
        println(" 0 Return to main menu")
        println(" 1 Assign trajectory file (xtc or trr), current: $trjfilename")
        println(" 2 Assign index file (ndx), current: $ndxfilename")
        println(" 3 Select ligand groups, current: $ligand_grp $(ligand_grp != -1 ? ndx.groups[ligand_grp + 1].name : "")")
        println(" 4 Select receptor groups, current: $receptor_grp $(receptor_grp != -1 ? ndx.groups[receptor_grp + 1].name : "")")
        println(" 5 Select complex groups, current: $complex_grp $(complex_grp != -1 ? ndx.groups[complex_grp + 1].name : "")")
        println(" 6 Do MM-PBSA calculations now!")
        i = sel_fun(Int32)
        if i == 0
            return
        elseif i == -2
            useTS = !useTS
        elseif i == -1
            useDH = !useDH
        elseif i == 1
            request_hint("Input trajectory file name (default: ?md.xtc):\n")
            trjfilename = get_file("?md.xtc"; infilename=tprfilename)
        elseif i == 2
            request_hint("Input index file name (default: ?index.ndx):\n")
            ndxfilename = get_file("?index.ndx"; infilename=tprfilename)
            ndx = IndexParser.gen_ndx_from_file(ndxfilename)
        elseif i == 3
            if length(ndx.groups) == 0
                error_hint("Assign index file first (function 2).")
                continue
            end
            IndexParser.list_groups(ndx)
            request_hint("Input ligand group num: ")
            ligand_grp = get_input(-1, Int32)
            if !(0 <= ligand_grp < length(ndx.groups))
                error_hint("Error: invalid input $ligand_grp.\n")
                ligand_grp = -1
            end
        elseif i == 4
            if length(ndx.groups) == 0
                error_hint("Assign index file first (function 2).")
                continue
            end
            IndexParser.list_groups(ndx)
            request_hint("Input receptor group num: ")
            receptor_grp = get_input(-1, Int32)
            if !(0 <= receptor_grp < length(ndx.groups))
                error_hint("Error: invalid input $receptor_grp.\n")
                receptor_grp = -1
            end
        elseif i == 5
            if length(ndx.groups) == 0
                error_hint("Assign index file first (function 2).")
                continue
            end
            IndexParser.list_groups(ndx)
            request_hint("Input complex group num: ")
            complex_grp = get_input(-1, Int32)
            if !(0 <= receptor_grp < length(ndx.groups))
                error_hint("Error: invalid input $complex_grp.\n")
                complex_grp = -1
            end
        elseif i == 6
            if trjfilename == ""
                error_hint("Trajectory undefined. Use function 1 to assign trajectory file.\n")
                continue
            elseif length(ndx.groups) == 0
                error_hint("Index undefined. Use function 2 to assign index file.\n")
                continue
            elseif ligand_grp == -1
                error_hint("Ligand group undefined. Use function 3 to assign ligand group.\n")
                continue
            elseif receptor_grp == -1
                error_hint("Receptor group undefined. Use function 4 to assign receptor group.\n")
                continue
            elseif complex_grp == -1
                error_hint("Complex group undefined. Use function 5 to assign complex group.\n")
                continue
            else
                Tpr.do_mmpbsa(mdp, trjfilename, ndx, complex_grp, receptor_grp, ligand_grp, ndxfilename, tprfilename, settings)
            end
        end
    end
end

function check_programs_validity(settings)
    # test gromacs
    gmx = settings["environments"]["gmx"]
    try
        if any(map(l -> startswith(l, "GROMACS version"), readlines(`$gmx --version`)))
            finish_hint("GROMACS status: OK\n")
        end
    catch
        error_hint("GROMACS status: ERROR\n")
        return false
    end
    # test apbs
    apbs = settings["environments"]["apbs"]
    try
        run(pipeline(`$apbs --version`, stdout="apbs_out.txt", stderr=devnull))
    catch
        if any(map(l -> contains(l, "Poisson-Boltzmann"), readlines("apbs_out.txt")))
            finish_hint("APBS status: OK\n")
        else
            error_hint("APBS status: ERROR\n")
        end
    finally
        rm("apbs_out.txt")
        rm("io.mc")
    end
    return true
end

end